/**
 * 防抖：让一定时间内连续触发的函数只触发一次
 * @param fn
 * @param wait
 * @param immediate
 */
export function debounce(fn: any, wait: unknown, immediate: unknown) {
    /*--------------------------------------- -start- 参数处理 ---------------------------------------*/
    if (typeof fn !== 'function') throw TypeError('fn must be function')
    if (typeof wait === 'boolean') {
        immediate = wait
        wait = 500
    }
    if (wait) {
        if (typeof wait !== 'number') throw TypeError('wait must be number')
    } else {
        wait = 500
    }
    /*--------------------------------------- -end- ---------------------------------------*/
    let timer: number | undefined = undefined
    return function proxy(this: any, event: EventTarget, ...args: Array<any>) {
        const self = this
        // 如果传入的immediate为真，而且timer为空(即定时器还没有设置或已经执行过了)，就立即执行
        const _immediate = immediate && !timer
        // 如果下次触发到来，则停止掉之前的定时器
        clearTimeout(timer)
        // 让传入的函数延后wait这么久再执行
        // @ts-ignore
        timer = setTimeout(() => {
            // 到时间后重置定时器，方便下次判断
            timer = undefined
            // 定时器到时间后如果传入的immediate为假，则执行传入的函数
            !immediate && fn.call(self, event, ...args)
        }, <number>wait)
        // 立即执行一次
        _immediate && fn.call(self, event, ...args)
    }
}